#region Copyright (c) 2006-2011 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2011 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Widgetsphere.Generator.Common.Util;
using Widgetsphere.Generator.Models;

namespace Widgetsphere.Generator.DAL.ProjectItemGenerators.BusinessViewCollection
{
	class BusinessViewCollectionGeneratedTemplate : DomainProjectTemplate
	{
		private readonly StringBuilder sb = new StringBuilder();
		private readonly CustomView _currentView;

		public BusinessViewCollectionGeneratedTemplate(ModelRoot model, CustomView currentView)
		{
			_model = model;
			_currentView = currentView;
		}

		#region BaseClassTemplate overrides
		public override string FileName
		{
			get { return string.Format("{0}Collection.Generated.cs", _currentView.PascalName); }
		}

		public string ParentItemName
		{
			get { return string.Format("{0}Collection.cs", _currentView.PascalName); }
		}

		public override string FileContent
		{
			get
			{
				GenerateContent();
				return sb.ToString();
			}
		}
		#endregion

		#region GenerateContent

		private void GenerateContent()
		{
			try
			{
				Widgetsphere.Generator.GenerationHelper.AppendCopyrightInCode(sb, _model);
				this.AppendUsingStatements();
				sb.AppendLine("namespace " + this.GetLocalNamespace() + ".Business.Views");
				sb.AppendLine("{");
				this.AppendClass();
				this.AppendSearchClass();
				sb.AppendLine("}");
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		#endregion

		#region namespace / objects

		public void AppendUsingStatements()
		{
			sb.AppendLine("using System;");
			sb.AppendLine("using System.Linq;");
			sb.AppendLine("using System.Data;");
			sb.AppendLine("using System.Xml;");
			sb.AppendLine("using System.Collections.Generic;");
			sb.AppendLine("using System.Collections;");
			sb.AppendLine("using System.Runtime.Serialization;");
			sb.AppendLine("using System.ComponentModel;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.Rules;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.SelectCommands;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Domain.Objects;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Domain.Views;");
			sb.AppendLine("using Widgetsphere.Core.DataAccess;");
			sb.AppendLine("using Widgetsphere.Core.Util;");
			sb.AppendLine("using Widgetsphere.Core.Logging;");
			sb.AppendLine("using Widgetsphere.Core.Exceptions;");
			sb.AppendLine("using System.IO;");
			sb.AppendLine("using System.Linq.Expressions;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.Objects;");
			sb.AppendLine("using System.Data.Linq;");
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.LINQ;");
			sb.AppendLine("using System.Text.RegularExpressions;");
			sb.AppendLine("using System.Text;");
			sb.AppendLine();
		}

		private void AppendClass()
		{
			sb.AppendLine();
			sb.AppendLine("	/// <summary>");
			sb.AppendLine("	/// The class representing the '" + _currentView.PascalName + "' virtual database table");
			sb.AppendLine("	/// </summary>");
			sb.AppendLine("	[Serializable()]");
			sb.AppendLine("	public partial class " + _currentView.PascalName + "Collection : Widgetsphere.Core.DataAccess.BusinessCollectionBase, Widgetsphere.Core.DataAccess.IReadOnlyBusinessCollection, System.Collections.Generic.IEnumerable<" + _currentView.PascalName + ">, System.ComponentModel.IListSource, System.Collections.IList");
			sb.AppendLine("	{");
			this.AppendMemberVariables();
			this.AppendConstructors();
			this.AppendProperties();
			this.AppendOperatorIndexer();
			this.AppendMethods();
			this.AppendAggregateMethods();
			this.AppendMethodContainsIndexOf();
			this.AppendMethodIListInterface();
			this.AppendClassEnumerator();
			this.AppendIBusinessCollectionRegion();
			sb.AppendLine("	}");
			sb.AppendLine();
			this.AppendPagingClass();
		}

		#region Aggregate Methods

		private void AppendAggregateMethods()
		{
			var scope = string.Empty;

			//List<Table> tableList = _currentView.GetTableHierarchy();
			//tableList.Remove(_currentView);
			var columnList = new Dictionary<string, CustomViewColumn>();

			//Need the colums in order from base UP
			foreach (var column in _currentView.GetColumns().OrderBy(x => x.PascalName))
			{
				if (column.Generated)
				{
					columnList.Add(column.DatabaseName.ToLower(), column);
				}
			}

			//All types that are valid for these operations
			var typeList = new List<string>();
			typeList.Add("int");
			typeList.Add("Single");
			typeList.Add("double");
			typeList.Add("decimal");
			typeList.Add("string");
			typeList.Add("DateTime");

			//Max
			this.AppendAggregateMax(scope, columnList, typeList);

			//Min
			this.AppendAggregateMin(scope, columnList, typeList);

			typeList = new List<string>();
			typeList.Add("int");
			typeList.Add("Single");
			typeList.Add("double");
			typeList.Add("decimal");

			//Average
			this.AppendAggregateAverage(scope, columnList, typeList);

			//Sum
			this.AppendAggregateSum(scope, columnList, typeList);

			typeList = new List<string>();
			typeList.Add("int");
			typeList.Add("Single");
			typeList.Add("double");
			typeList.Add("decimal");
			typeList.Add("string");
			typeList.Add("DateTime");
			typeList.Add("Guid");

			//Count
			this.AppendAggregateCount(scope, columnList);

			//Distinct
			this.AppendAggregateDistinct(scope, columnList, typeList);

		}

		private void AppendAggregateSum(string scope, Dictionary<string, CustomViewColumn> columnList, List<string> typeList)
		{
			foreach (var typeName in typeList)
			{
				AppendAggregateSumBody(scope, columnList, typeName);
				if (typeName != "string")
					AppendAggregateSumBody(scope, columnList, typeName + "?");
			}
		}

		private void AppendAggregateSumBody(string scope, Dictionary<string, CustomViewColumn> columnList, string typeName)
		{
			var returnType = "double";
			if (typeName.StartsWith("decimal")) returnType = "decimal";

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the summary value of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetSum(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetSum(select, x => true);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the summary value of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetSum(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetSum(select, where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the summary value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetSum(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			string fieldName = ((System.Linq.Expressions.MemberExpression)(select.Body)).Member.Name;");
			sb.AppendLine("			switch (fieldName.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in _currentView.GetColumns().Where(x => x.Generated))
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": fieldName = \"" + column.DatabaseName + "\"; break;");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"SELECT SUM([\" + parser.GetTableAlias(fieldName, \"" + _currentView.DatabaseName + "\") + \"].\" + fieldName + \") \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			object p = cmd.ExecuteScalar();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			if (p == System.DBNull.Value)");
			sb.AppendLine("				return null;");
			sb.AppendLine("			else");
			sb.AppendLine("				return (" + typeName + ")p;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendAggregateAverage(string scope, Dictionary<string, CustomViewColumn> columnList, List<string> typeList)
		{
			foreach (var typeName in typeList)
			{
				AppendAggregateAverageBody(scope, columnList, typeName);
				if (typeName != "string")
					AppendAggregateAverageBody(scope, columnList, typeName + "?");
			}
		}

		private void AppendAggregateAverageBody(string scope, Dictionary<string, CustomViewColumn> columnList, string typeName)
		{
			var returnType = "double";
			if (typeName.StartsWith("decimal")) returnType = "decimal";

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the average value of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetAverage(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetAverage(select, x => true);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the average value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetAverage(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetAverage(select, where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the average value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + returnType + "? GetAverage(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			string fieldName = ((System.Linq.Expressions.MemberExpression)(select.Body)).Member.Name;");
			sb.AppendLine("			switch (fieldName.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in _currentView.GetColumns().Where(x => x.Generated))
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": fieldName = \"" + column.DatabaseName + "\"; break;");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"SELECT AVG([\" + parser.GetTableAlias(fieldName, \"" + _currentView.DatabaseName + "\") + \"].\" + fieldName + \") \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			object p = cmd.ExecuteScalar();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			if (p == System.DBNull.Value)");
			sb.AppendLine("				return null;");
			sb.AppendLine("			else");
			sb.AppendLine("				return (" + typeName + ")p;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendAggregateDistinct(string scope, Dictionary<string, CustomViewColumn> columnList, List<string> typeList)
		{
			foreach (var typeName in typeList)
			{
				AppendAggregateDistinctBody(scope, columnList, typeName);
				if (typeName != "string")
					AppendAggregateDistinctBody(scope, columnList, typeName + "?");
			}
		}

		private void AppendAggregateDistinctBody(string scope, Dictionary<string, CustomViewColumn> columnList, string typeName)
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get a list of distinct values of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		public static " + scope + "IEnumerable<" + typeName + "> GetDistinct(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetDistinct(select, x => true);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get a list of distinct values of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + "IEnumerable<" + typeName + "> GetDistinct(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetDistinct(select, where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get a list of distinct values of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + "IEnumerable<" + typeName + "> GetDistinct(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			string fieldName = ((System.Linq.Expressions.MemberExpression)(select.Body)).Member.Name;");
			sb.AppendLine("			switch (fieldName.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in _currentView.GetColumns().Where(x => x.Generated))
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": fieldName = \"" + column.DatabaseName + "\"; break;");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"SELECT DISTINCT([\" + parser.GetTableAlias(fieldName, \"" + _currentView.DatabaseName + "\") + \"].\" + fieldName + \") \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			System.Data.Common.DbDataReader dr = cmd.ExecuteReader();");
			sb.AppendLine();
			sb.AppendLine("			var retval = new List<" + typeName + ">();");
			sb.AppendLine("			while (dr.Read())");
			sb.AppendLine("			{");
			sb.AppendLine("				if (!dr.IsDBNull(0))");
			sb.AppendLine("				{");
			sb.AppendLine("					object o = dr[0];");
			sb.AppendLine("					retval.Add((" + typeName + ")o);");
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine();
			sb.AppendLine("			return retval;");
			sb.AppendLine();
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendAggregateMin(string scope, Dictionary<string, CustomViewColumn> columnList, List<string> typeList)
		{
			foreach (var typeName in typeList)
			{
				AppendAggregateMinBody(scope, columnList, typeName);
				if (typeName != "string")
					AppendAggregateMinBody(scope, columnList, typeName + "?");
			}
		}

		private void AppendAggregateMinBody(string scope, Dictionary<string, CustomViewColumn> columnList, string typeName)
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the minimum value of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMin(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetMin(select, x => true);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the minimum value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMin(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetMin(select, where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the minimum value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMin(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			string fieldName = ((System.Linq.Expressions.MemberExpression)(select.Body)).Member.Name;");
			sb.AppendLine("			switch (fieldName.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in _currentView.GetColumns().Where(x => x.Generated))
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": fieldName = \"" + column.DatabaseName + "\"; break;");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"SELECT MIN([\" + parser.GetTableAlias(fieldName, \"" + _currentView.DatabaseName + "\") + \"].\" + fieldName + \") \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			object p = cmd.ExecuteScalar();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			if (p == System.DBNull.Value)");
			sb.AppendLine("				return null;");
			sb.AppendLine("			else");
			sb.AppendLine("				return (" + typeName + ")p;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendAggregateMax(string scope, Dictionary<string, CustomViewColumn> columnList, List<string> typeList)
		{
			foreach (var typeName in typeList)
			{
				AppendAggregateMaxBody(scope, columnList, typeName);
				if (typeName != "string")
					AppendAggregateMaxBody(scope, columnList, typeName + "?");
			}
		}

		private void AppendAggregateMaxBody(string scope, Dictionary<string, CustomViewColumn> columnList, string typeName)
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the maximum value of the field for all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMax(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetMax(select, x => true);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the maximum value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMax(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetMax(select, where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the maximum value of the field in the set of records that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"select\">The field to aggregate</param>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + typeName.Replace("?", "") + ((typeName == "string") ? "" : "?") + " GetMax(Expression<Func<" + _currentView.PascalName + "Query, " + typeName + ">> select, Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			string fieldName = ((System.Linq.Expressions.MemberExpression)(select.Body)).Member.Name;");
			sb.AppendLine("			switch (fieldName.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in _currentView.GetColumns().Where(x => x.Generated))
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": fieldName = \"" + column.DatabaseName + "\"; break;");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"SELECT MAX([\" + parser.GetTableAlias(fieldName, \"" + _currentView.DatabaseName + "\") + \"].\" + fieldName + \") \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			object p = cmd.ExecuteScalar();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			if (p == System.DBNull.Value)");
			sb.AppendLine("				return null;");
			sb.AppendLine("			else");
			sb.AppendLine("				return (" + typeName + ")p;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendAggregateCount(string scope, Dictionary<string, CustomViewColumn> columnList)
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the count of all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static " + scope + "int GetCount()");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetCount(x => true, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the count of all objects");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static " + scope + "int GetCount(QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetCount(x => true, optimizer);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the count of objects that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + scope + "int GetCount(Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return GetCount(where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Get the count of objects that match the Where condition");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">An object to specify querying parameters and return profiling information</param>");
			sb.AppendLine("		public static " + scope + "int GetCount(Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine();
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = \"select count(*) \" + parser.GetFromClause(optimizer) + \" \" + parser.GetWhereClause() + string.Empty;");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			object p = cmd.ExecuteScalar();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			return (int)p;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		#endregion

		private void AppendIBusinessCollectionRegion()
		{
			sb.AppendLine("		#region IBusinessCollection Explicit Members");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Returns an item in this collection by index.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"index\">The zero-based index of the element to get or set. </param>");
			sb.AppendLine("		/// <returns>The element at the specified index.</returns>");
			sb.AppendLine("		IBusinessObject IBusinessCollection.this[int index]");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return this[index]; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		Enum IBusinessCollection.Collection");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return this.Collection; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		Type IBusinessCollection.ContainedType");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return this.ContainedType; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		SubDomainBase IBusinessCollection.SubDomain");
			sb.AppendLine("			{");
			sb.AppendLine("				get { return this.SubDomain; }");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("		 Type ITyped.GetContainedType()");
			sb.AppendLine("		 {");
			sb.AppendLine("			 return typeof(" + _currentView.PascalName + ");");
			sb.AppendLine("		 }");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendSearchClass()
		{
			var validColumns = GetValidSearchColumns();
			if (validColumns.Count != 0)
			{
				sb.AppendLine("	#region " + _currentView.PascalName + "Search");
				sb.AppendLine();
				sb.AppendLine("	/// <summary>");
				sb.AppendLine("	/// The search object for the " + _currentView.PascalName + "Collection.");
				sb.AppendLine("	/// </summary>");
				sb.AppendLine("	[Serializable]");
				sb.AppendLine("	public class " + _currentView.PascalName + "Search : IBusinessObjectSearch");
				sb.AppendLine("	{");
				sb.AppendLine();
				sb.AppendLine("		private int _maxRowCount = 0;");
				foreach (CustomViewColumn dc in validColumns)
				{
					sb.AppendFormat("		private " + dc.GetCodeType(true, true) + " _{0};", dc.CamelName).AppendLine();
				}
				sb.AppendLine("		private SearchType _searchType;");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Determines the maximum number of rows that are returned. Use 0 for no limit.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public int MaxRowCount");
				sb.AppendLine("		{");
				sb.AppendLine("			get { return _maxRowCount; }");
				sb.AppendLine("			set { _maxRowCount = value; }");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		int IBusinessObjectSearch.MaxRowCount");
				sb.AppendLine("		{");
				sb.AppendLine("			get { return this.MaxRowCount; }");
				sb.AppendLine("			set { this.MaxRowCount = value; }");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Determines the type of search to be performed.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public SearchType SearchType");
				sb.AppendLine("		{");
				sb.AppendLine("			get { return _searchType; }");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// A search object for the '" + _currentView.PascalName + "' collection.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public " + _currentView.PascalName + "Search(SearchType searchType) ");
				sb.AppendLine("		{");
				sb.AppendLine("			_searchType = searchType;");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		void IBusinessObjectSearch.SetValue(Enum field, object value)");
				sb.AppendLine("		{");
				sb.AppendLine("			this.SetValue((" + _currentView.PascalName + ".FieldNameConstants)field, value);");
				sb.AppendLine("		}");
				sb.AppendLine();
				sb.AppendLine("		/// <summary>");
				sb.AppendLine("		/// Set the specified value on this object.");
				sb.AppendLine("		/// </summary>");
				sb.AppendLine("		public void SetValue(" + _currentView.PascalName + ".FieldNameConstants field, object value)");
				sb.AppendLine("		{");
				foreach (CustomViewColumn dc in validColumns)
				{
					sb.AppendLine("			if (field == " + _currentView.PascalName + ".FieldNameConstants." + dc.PascalName + ")");
					sb.AppendLine("				this." + dc.PascalName + " = (" + dc.GetCodeType(false) + ")value;");
				}
				sb.AppendLine("		}");
				sb.AppendLine();
				foreach (CustomViewColumn dc in validColumns)
				{
					sb.AppendLine("		/// <summary>");
					sb.AppendLine("		/// This field determines the value of the '" + dc.PascalName + "' field on the '" + _currentView.PascalName + "' object when this search object is applied.");
					sb.AppendLine("		/// </summary>");
					sb.AppendFormat("		public " + dc.GetCodeType(true, true) + " {0}", dc.PascalName).AppendLine();
					sb.AppendLine("		{");
					sb.AppendFormat("			get {{ return _{0}; }}", dc.CamelName).AppendLine();
					sb.AppendFormat("			set {{ _{0} = value; }}", dc.CamelName).AppendLine();
					sb.AppendLine("		}");
					sb.AppendLine();
				}
				sb.AppendLine("	}");
				sb.AppendLine();
				sb.AppendLine("	#endregion ");
				sb.AppendLine();
			}
		}

		private ArrayList GetValidSearchColumns()
		{
			var validColumns = new ArrayList();
			foreach (var column in _currentView.GeneratedColumns)
			{
				if (!(column.DataType == System.Data.SqlDbType.Binary ||
					column.DataType == System.Data.SqlDbType.Image ||
					column.DataType == System.Data.SqlDbType.NText ||
					column.DataType == System.Data.SqlDbType.Text ||
					column.DataType == System.Data.SqlDbType.Timestamp ||
					column.DataType == System.Data.SqlDbType.Udt ||
					column.DataType == System.Data.SqlDbType.VarBinary ||
					column.DataType == System.Data.SqlDbType.Variant ||
					column.DataType == System.Data.SqlDbType.Money))
				{
					validColumns.Add(column);
				}
			}
			return validColumns;
		}

		private void AppendClassEnumerator()
		{
			sb.AppendLine("		#region IEnumerator");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// An strongly-typed enumerator for the '" + _currentView.PascalName + "' object collection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public partial class " + _currentView.PascalName + "Enumerator: System.Collections.IEnumerator ");
			sb.AppendLine("			{");
			sb.AppendLine("			private System.Collections.IEnumerator internalEnumerator;");
			sb.AppendLine("			internal " + _currentView.PascalName + "Enumerator(IEnumerator icg)");
			sb.AppendLine("			{");
			sb.AppendLine("				internalEnumerator = icg;");
			sb.AppendLine("			}");
			sb.AppendLine();

			sb.AppendLine("			#region IEnumerator Members");
			sb.AppendLine();
			sb.AppendLine("			/// <summary>");
			sb.AppendLine("			/// Reset the enumerator to the first object in this collection");
			sb.AppendLine("			/// </summary>");
			sb.AppendLine("			public void Reset()");
			sb.AppendLine("			{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				internalEnumerator.Reset();");
			sb.AppendLine("			}");
			Globals.AppendBusinessEntryCatch(sb);
			sb.AppendLine("			}");
			sb.AppendLine();

			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Gets the current element in the collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <returns>The current element in the collection.</returns>");
			sb.AppendLine("			public object Current");
			sb.AppendLine("			{");
			sb.AppendLine("				get");
			sb.AppendLine("				{");
			sb.AppendLine("					try");
			sb.AppendLine("					{");
			sb.AppendLine("						return new " + _currentView.PascalName + "((" + this.GetLocalNamespace() + ".Domain.Views.Domain" + _currentView.PascalName + ")internalEnumerator.Current);");
			sb.AppendLine("					}");
			Globals.AppendBusinessEntryCatch(sb, true);
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine();

			sb.AppendLine("			/// <summary>");
			sb.AppendLine("			/// Advances the enumerator to the next element of the collection.");
			sb.AppendLine("			/// </summary>");
			sb.AppendLine("			public bool MoveNext()");
			sb.AppendLine("			{");
			sb.AppendLine("				try");
			sb.AppendLine("				{");
			sb.AppendLine("					bool movedNext = internalEnumerator.MoveNext();");
			sb.AppendLine("					if (movedNext)");
			sb.AppendLine("					{");
			sb.AppendLine("						" + this.GetLocalNamespace() + ".Domain.Views.Domain" + _currentView.PascalName + " currentRow = (" + this.GetLocalNamespace() + ".Domain.Views.Domain" + _currentView.PascalName + ")internalEnumerator.Current;");
			sb.AppendLine("						while (currentRow.RowState == System.Data.DataRowState.Deleted || currentRow.RowState == System.Data.DataRowState.Detached)");
			sb.AppendLine("						{");
			sb.AppendLine("							movedNext = internalEnumerator.MoveNext();");
			sb.AppendLine("							if (!movedNext) break;");
			sb.AppendLine("							currentRow = (Domain" + _currentView.PascalName + ")internalEnumerator.Current;");
			sb.AppendLine("						}");
			sb.AppendLine("					}");
			sb.AppendLine("					return movedNext;");
			sb.AppendLine("				}");
			Globals.AppendBusinessEntryCatch(sb);
			sb.AppendLine("			}");
			sb.AppendLine();

			sb.AppendLine("			#endregion");
			sb.AppendLine();
			sb.AppendLine("		}");
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendPagingClass()
		{
			sb.AppendLine("	#region " + _currentView.PascalName + "Paging");
			sb.AppendLine();
			sb.AppendLine("	/// <summary>");
			sb.AppendLine("	/// A field sort object for the " + _currentView.PascalName + "Paging object.");
			sb.AppendLine("	/// </summary>");
			sb.AppendLine("	[Serializable]");
			sb.AppendLine("	public class " + _currentView.PascalName + "PagingFieldItem : IPagingFieldItem");
			sb.AppendLine("	{");
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the direction of the sort.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public bool Ascending { get; set; }");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the field on which to sort.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ".FieldNameConstants Field { get; set; }");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Create a sorting field object for the " + _currentView.PascalName + "Paging object.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"field\">The field on which to sort.</param>");
			sb.AppendLine("		public " + _currentView.PascalName + "PagingFieldItem(" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ".FieldNameConstants field)");
			sb.AppendLine("		{");
			sb.AppendLine("			this.Field = field;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Create a sorting field object for the " + _currentView.PascalName + "Paging object.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"field\">The field on which to sort.</param>");
			sb.AppendLine("		/// <param name=\"ascending\">Determines the direction of the sort.</param>");
			sb.AppendLine("		public " + _currentView.PascalName + "PagingFieldItem(" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ".FieldNameConstants field, bool ascending)");
			sb.AppendLine("			: this(field)");
			sb.AppendLine("		{");
			sb.AppendLine("			this.Ascending = ascending;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#region IPagingFieldItem Members");
			sb.AppendLine();
			sb.AppendLine("		System.Enum IPagingFieldItem.GetField()");
			sb.AppendLine("		{");
			sb.AppendLine("			return this.Field;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
			sb.AppendLine("	}");
			sb.AppendLine();
			sb.AppendLine("	/// <summary>");
			sb.AppendLine("	/// The paging object for the " + _currentView.PascalName + " collection");
			sb.AppendLine("	/// </summary>");
			sb.AppendLine("	[Serializable]");
			sb.AppendLine("	public class " + _currentView.PascalName + "Paging : PagingBase<" + _currentView.PascalName + "PagingFieldItem, " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ".FieldNameConstants> { }");
			sb.AppendLine();
			sb.AppendLine("	#endregion");
			sb.AppendLine();
		}

		#endregion

		#region append regions
		#endregion

		#region append member variables
		public void AppendMemberVariables()
		{
			sb.AppendLine("		#region Member Variables");
			sb.AppendLine();
			sb.AppendLine("		internal Domain" + _currentView.PascalName + "Collection wrappedClass;");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}
		#endregion

		#region append constructors
		public void AppendConstructors()
		{
			sb.AppendLine("		#region Constructor / Initialize");
			sb.AppendLine();
			AppendConstructorDomainClass();
			AppendConstructorDefault();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendConstructorDomainClass()
		{
			sb.AppendLine("		internal " + _currentView.PascalName + "Collection(Domain" + _currentView.PascalName + "Collection classToWrap)");
			sb.AppendLine("		{");
			sb.AppendLine("			wrappedClass = classToWrap;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendConstructorDefault()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// The default constructor");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public " + _currentView.PascalName + "Collection() ");
			sb.AppendLine("		{");
			//sb.AppendLine("			var sd = new SubDomain(\"Default Contructor Called\");");
			sb.AppendLine("			var sd = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine("			wrappedClass = (Domain" + _currentView.PascalName + "Collection)sd.GetDomainCollection(Collections." + _currentView.PascalName + "Collection);");
			sb.AppendLine("		}");
			sb.AppendLine();
		}
		#endregion

		#region append properties
		private void AppendProperties()
		{
			sb.AppendLine("		#region Property Implementations");
			sb.AppendLine();
			AppendPropertyWrappedClass();
			AppendPropertySubDomain();
			AppendPropertyCount();
			AppendPropertyContainedType();
			AppendPropertyCollection();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendPropertyWrappedClass()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Returns the internal object that this object wraps");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		[System.ComponentModel.Browsable(false)]");
			sb.AppendLine("		public object WrappedClass");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return wrappedClass; }");
			sb.AppendLine("			set { wrappedClass = (Domain" + _currentView.PascalName + "Collection)value; }");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendPropertySubDomain()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// A reference to the SubDomain that holds this collection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public SubDomain SubDomain");
			sb.AppendLine("		{");
			sb.AppendLine("			get");
			sb.AppendLine("			{");
			sb.AppendLine("				try");
			sb.AppendLine("				{");
			sb.AppendLine("					return wrappedClass.SubDomain;");
			sb.AppendLine("				}");
			Globals.AppendBusinessEntryCatch(sb, true);
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendPropertyCount()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Returns the number of items in this collection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public override int Count");
			sb.AppendLine("		{");
			sb.AppendLine("			get");
			sb.AppendLine("			{");
			sb.AppendLine("				try");
			sb.AppendLine("				{");
			sb.AppendLine("					DataTable dt = wrappedClass.GetChanges(DataRowState.Deleted);");
			sb.AppendLine("					if (dt == null)");
			sb.AppendLine("						return wrappedClass.Count;");
			sb.AppendLine("					else");
			sb.AppendLine("						return wrappedClass.Count - dt.Rows.Count;");
			sb.AppendLine("				}");
			Globals.AppendBusinessEntryCatch(sb, true);
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendPropertyContainedType()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the type of object contained by this collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public Type ContainedType");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return typeof(" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + "); }");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendPropertyCollection()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the type of collection for this object.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public Collections Collection");
			sb.AppendLine("		{");
			sb.AppendFormat("			get {{ return Collections.{0}Collection; }}", _currentView.PascalName).AppendLine();
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		#endregion

		#region append methods

		public void AppendMethods()
		{
			sb.AppendLine("		#region Methods");
			sb.AppendLine();
			this.AppendOtherMethods();
			this.AppendMethodSelectAll();
			this.AppendMethodSelectLINQ();
			this.AppendLoadRow();
			//this.AppendMethodSelectSearch();
			//this.AppendMethodSelectPaged();
			//this.AppendMethodSelectParameter();
			this.AppendRegionSearch();
			this.AppendMethodGetSorted();
			this.AppendMethodGetEnumerator();
			this.AppendRejectChanges();
			this.AppendMethodVisitor();
			this.AppendStaticSQLMethods();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendMethodSelectLINQ()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a result set");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		public static " + _currentView.PascalName + "Collection RunSelect(Expression<Func<" + _currentView.PascalName + "Query, bool>> where)");
			sb.AppendLine("		{");
			sb.AppendLine("			return RunSelect(where, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a paged result set");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static " + _currentView.PascalName + "Collection RunSelect(Expression<Func<" + _currentView.PascalName + "Query, bool>> where, " + _currentView.PascalName + "Paging paging)");
			sb.AppendLine("		{");
			sb.AppendLine("			return RunSelect(where, paging, new QueryOptimizer());");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a paged result set");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static " + _currentView.PascalName + "Collection RunSelect(Expression<Func<" + _currentView.PascalName + "Query, bool>> where, " + _currentView.PascalName + "Paging paging, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (paging == null) throw new Exception(\"The paging object cannot be null.\");");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine();
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, paging, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = parser.GetSQL(optimizer);");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			var startTime = DateTime.Now;");
			sb.AppendLine("			var result = dc.Translate<" + _currentView.PascalName + "Query>(cmd.ExecuteReader());");
			sb.AppendLine("			var endTime = DateTime.Now;");
			sb.AppendLine("			optimizer.TotalMilliseconds = (long)endTime.Subtract(startTime).TotalMilliseconds;");
			sb.AppendLine("			" + _currentView.PascalName + "Collection retval = subDomain.GetCollection<" + _currentView.PascalName + "Collection>();");
			sb.AppendLine("			foreach (var item in result)");
			sb.AppendLine("			{");
			sb.AppendLine("				var newItem = retval.NewItem();");
			sb.AppendLine("				LoadDataRow(item, newItem);");
			sb.AppendLine("				retval.AddItem(newItem);");
			sb.AppendLine("			}");
			sb.AppendLine("			retval.wrappedClass.AcceptChanges();");
			sb.AppendLine("			retval.wrappedClass.EndLoadData();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			paging.RecordCount = GetCount(where);");
			sb.AppendLine("			return retval;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Using the specified Where expression, execute a query against the database to return a result set");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"where\">The expression that determines the records selected</param>");
			sb.AppendLine("		/// <param name=\"optimizer\">The optimization object</param>");
			sb.AppendLine("		public static " + _currentView.PascalName + "Collection RunSelect(Expression<Func<" + _currentView.PascalName + "Query, bool>> where, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var subDomain = new SubDomain(ConfigurationValues.GetInstance().Modifier);");
			sb.AppendLine();
			sb.AppendLine("			var dc = new DataContext(ConfigurationValues.GetInstance().ConnectionString);");
			sb.AppendLine("			Table<" + _currentView.PascalName + "Query> template = dc.GetTable<" + _currentView.PascalName + "Query>();");
			sb.AppendLine("			var cmd = BusinessCollectionPersistableBase.GetCommand<" + _currentView.PascalName + "Query>(dc, template, where);");
			sb.AppendLine("			cmd.CommandTimeout = ConfigurationValues.GetInstance().DefaultTimeOut;");
			sb.AppendLine("			var parser = LinqSQLParser.Create(cmd.CommandText, LinqSQLParser.ObjectTypeConstants.View);");
			sb.AppendLine("			cmd.CommandText = parser.GetSQL(optimizer);");
			sb.AppendLine("			dc.Connection.Open();");
			sb.AppendLine("			var startTime = DateTime.Now;");
			sb.AppendLine("			var result = dc.Translate<" + _currentView.PascalName + "Query>(cmd.ExecuteReader());");
			sb.AppendLine("			var endTime = DateTime.Now;");
			sb.AppendLine("			optimizer.TotalMilliseconds = (long)endTime.Subtract(startTime).TotalMilliseconds;");
			sb.AppendLine("			" + _currentView.PascalName + "Collection retval = subDomain.GetCollection<" + _currentView.PascalName + "Collection>();");
			sb.AppendLine("			foreach (var item in result)");
			sb.AppendLine("			{");
			sb.AppendLine("				" + _currentView.PascalName + " newItem = retval.NewItem();");
			sb.AppendLine("				LoadDataRow(item, newItem);");
			sb.AppendLine("				retval.AddItem(newItem);");
			sb.AppendLine("			}");
			sb.AppendLine("			retval.wrappedClass.AcceptChanges();");
			sb.AppendLine("			retval.wrappedClass.EndLoadData();");
			sb.AppendLine("			dc.Connection.Close();");
			sb.AppendLine("			return retval;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendLoadRow()
		{
			sb.AppendLine("		private static void LoadDataRow(" + _currentView.PascalName + "Query item, " + _currentView.PascalName + " newItem)");
			sb.AppendLine("		{");
			foreach (var column in _currentView.GetColumns().OrderBy(x => x.PascalName))
			{
				if (column.AllowNull)
					sb.AppendLine("			newItem.wrappedClass[\"" + column.DatabaseName + "\"] = StringHelper.ConvertToDatabase(item." + column.PascalName + ");");
				else
					sb.AppendLine("			newItem.wrappedClass[\"" + column.DatabaseName + "\"] = item." + column.PascalName + ";");
			}
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendOtherMethods()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Create a new object to later add to this collection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		internal " + _currentView.PascalName + " NewItem()");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				lock (wrappedClass.SubDomain)");
			sb.AppendLine("				{");
			sb.AppendLine("					return new " + _currentView.PascalName + "(wrappedClass.NewItem());");
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine("			catch (System.Data.DBConcurrencyException dbcex) { throw new Widgetsphere.Core.Exceptions.ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }");
			sb.AppendLine("			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new Widgetsphere.Core.Exceptions.UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }");
			sb.AppendLine("			catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Add a newly created entity to this collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		internal virtual void AddItem(" + _currentView.PascalName + " item)");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				lock (wrappedClass.SubDomain)");
			sb.AppendLine("				{");
			sb.AppendLine("					wrappedClass.AddItem((Domain" + _currentView.PascalName + ")item.WrappedClass);");
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine("			catch (System.Data.DBConcurrencyException dbcex) { throw new Widgetsphere.Core.Exceptions.ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }");
			sb.AppendLine("			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new Widgetsphere.Core.Exceptions.UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }");
			sb.AppendLine("			catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendMethodVisitor()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Takes an IVisitor object and iterates through each item in this collection");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"visitor\">The object that processes each collection item</param>");
			sb.AppendLine("		public virtual void ProcessVisitor(IVisitor visitor)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (visitor == null) throw new Exception(\"This object cannot be null.\");");
			sb.AppendLine("			foreach (IBusinessObject item in this)");
			sb.AppendLine("			{");
			sb.AppendLine("				visitor.Visit(item);");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendStaticSQLMethods()
		{
			sb.AppendLine("		#region Static SQL Methods");
			sb.AppendLine();

			var allColumns = _currentView.GetColumns().Where(x => x.Generated).ToList();

			#region GetFieldAliasFromFieldNameSqlMapping
			sb.AppendLine("		internal static string GetFieldAliasFromFieldNameSqlMapping(string alias)");
			sb.AppendLine("		{");
			sb.AppendLine("			alias = alias.Replace(\"[\", string.Empty).Replace(\"]\", string.Empty);");
			sb.AppendLine("			switch (alias.ToLower())");
			sb.AppendLine("			{");
			foreach (var column in allColumns)
			{
				sb.AppendLine("				case \"" + column.DatabaseName.ToLower() + "\": return \"" + column.PascalName.ToLower() + "\";");
			}
			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			#endregion

			#region GetTableFromFieldAliasSqlMapping
			sb.AppendLine("		internal static string GetTableFromFieldAliasSqlMapping(string alias)");
			sb.AppendLine("		{");
			sb.AppendLine("			switch (alias.ToLower())");
			sb.AppendLine("			{");

			foreach (var column in allColumns)
			{
				sb.AppendLine("				case \"" + column.PascalName.ToLower() + "\": return \"" + _currentView.DatabaseName + "\";");
			}

			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			#endregion

			#region GetTableFromFieldNameSqlMapping
			sb.AppendLine("		internal static string GetTableFromFieldNameSqlMapping(string field)");
			sb.AppendLine("		{");
			sb.AppendLine("			switch (field.ToLower())");
			sb.AppendLine("			{");

			foreach (var column in allColumns)
			{
				sb.AppendLine("				case \"" + column.DatabaseName.ToLower() + "\": return \"" + _currentView.DatabaseName + "\";");
			}

			sb.AppendLine("				default: throw new Exception(\"The select clause is not valid.\");");
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			#endregion

			#region GetRemappedLinqSql
			sb.AppendLine("		internal static string GetRemappedLinqSql(string sql, string parentAlias, LinqSQLFromClauseCollection childTables)");
			sb.AppendLine("		{");
			foreach (var column in allColumns)
			{
				sb.AppendLine("			sql = System.Text.RegularExpressions.Regex.Replace(sql, \"\\\\[\" + parentAlias + \"\\\\]\\\\.\\\\[" + column.DatabaseName.ToLower() + "\\\\]\", \"[\" + childTables.GetBaseAliasTable(parentAlias, \"" + _currentView.DatabaseName + "\") + \"].[" + column.DatabaseName.ToLower() + "]\", RegexOptions.IgnoreCase);");
			}

			sb.AppendLine("			return sql;");
			sb.AppendLine("		}");
			sb.AppendLine();
			#endregion

			sb.AppendLine("		#endregion");
			sb.AppendLine();

			//GetPagedSQL
			sb.AppendLine("		internal static string GetPagedSQL(List<LinqSQLField> fieldList, LinqSQLFromClauseCollection fromLinkList, string whereClause, object paging, QueryOptimizer optimizer)");
			sb.AppendLine("		{");
			sb.AppendLine("			var sb = new StringBuilder();");
			sb.AppendLine("			var paging2 = (" + _currentView.PascalName + "Paging)paging;");
			sb.AppendLine();
			sb.AppendLine("			//Calculate the SELECT clause");
			sb.AppendLine("			sb.Append(\"SELECT \");");
			sb.AppendLine("			int index = 0;");
			sb.AppendLine("			foreach (LinqSQLField field in fieldList)");
			sb.AppendLine("			{");
			sb.AppendLine("				sb.Append(\"[t0].[\" + field.Name + \"]\");");
			sb.AppendLine("				if (index < fieldList.Count - 1) sb.Append(\", \");");
			sb.AppendLine("				index++;");
			sb.AppendLine("			}");
			sb.AppendLine("			sb.AppendLine();");
			sb.AppendLine("			sb.AppendLine(\"FROM (\");");
			sb.AppendLine();
			sb.AppendLine("			//Calculate the Inner SELECT clause");
			sb.AppendLine("			sb.Append(\"SELECT \");");
			sb.AppendLine("			index = 0;");
			sb.AppendLine("			foreach (var field in fieldList)");
			sb.AppendLine("			{");
			sb.AppendLine("				sb.Append(field.GetSQL(false));");
			sb.AppendLine("				if (index < fieldList.Count - 1) sb.Append(\", \");");
			sb.AppendLine("				index++;");
			sb.AppendLine("			}");
			sb.AppendLine("			sb.AppendLine();");
			sb.AppendLine();

			sb.AppendLine("			//If there is no sort then add primary key");
			sb.AppendLine("			if (paging2.OrderByList.Count == 0)");
			sb.AppendLine("			{");
			foreach (var column in _currentView.PrimaryKeyColumns.OrderBy(x => x.Name))
			{
				sb.AppendLine("				paging2.OrderByList.Add(new " + _currentView.PascalName + "PagingFieldItem(" + _currentView.PascalName + ".FieldNameConstants." + column.PascalName + "));");
			}
			sb.AppendLine("			}");
			sb.AppendLine();

			//Add the paging column determination code
			sb.AppendLine("			//Determine the paging sort");
			sb.AppendLine("			var orderByClause = string.Empty;");
			sb.AppendLine("			foreach (var fieldItem in paging2.OrderByList)");
			sb.AppendLine("			{");
			sb.AppendLine("				if (!string.IsNullOrEmpty(orderByClause)) orderByClause += \", \";");
			sb.AppendLine("				switch (fieldItem.Field.ToString().ToLower())");
			sb.AppendLine("				{");
			foreach (var column in allColumns)
			{
				sb.Append("					case \"" + column.PascalName.ToLower() + "\": orderByClause += \"[\" + (from x in fieldList where x.Alias.ToLower() == fieldItem.Field.ToString().ToLower() select x).FirstOrDefault().Table + \"].[" + column.DatabaseName + "]\" + (fieldItem.Ascending ? string.Empty : \" DESC\"); ");
				if (_currentView.PrimaryKeyColumns.Count == 1 && (_currentView.PrimaryKeyColumns[0] == column))
					sb.Append("isPrimary = true;");
				sb.AppendLine("break;");
			}

			sb.AppendLine("					default: throw new Exception(\"The order by clause is not valid.\");");
			sb.AppendLine("				}");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			sb.AppendLine(\", ROW_NUMBER() OVER (ORDER BY \" + orderByClause + \") AS Row\");");
			sb.AppendLine("			//Calculate the FROM clause");
			sb.AppendLine("			index = 0;");
			sb.AppendLine("			sb.Append(\"FROM \");");
			sb.AppendLine("			foreach (LinqSQLFromClause fromClause in fromLinkList)");
			sb.AppendLine("			{");
			sb.AppendLine("				sb.Append(\"[\" + fromClause.Schema + \"].[\" + fromClause.TableName + \"] AS [\" + fromClause.Alias + \"] \");");
			sb.AppendLine("				if (optimizer.NoLocking) sb.Append(\"WITH (NOLOCK)\");");
			sb.AppendLine("				if (!string.IsNullOrEmpty(fromClause.LinkClause)) sb.Append(fromClause.LinkClause + \" \");");
			sb.AppendLine();
			sb.AppendLine("				if (index < fromLinkList.Count - 1)");
			sb.AppendLine("				{");
			sb.AppendLine("					sb.AppendLine();");
			sb.AppendLine("					sb.Append(\"LEFT OUTER JOIN \");");
			sb.AppendLine("				}");
			sb.AppendLine();
			sb.AppendLine("				index++;");
			sb.AppendLine("			}");
			sb.AppendLine("			sb.AppendLine();");
			sb.AppendLine();
			sb.AppendLine("			//Calculate the WHERE clause");
			sb.AppendLine("			if (!string.IsNullOrEmpty(whereClause))");
			sb.AppendLine("			{");
			sb.AppendLine("				foreach (LinqSQLFromClause fromClause in fromLinkList)");
			sb.AppendLine("				{");
			sb.AppendLine("					//Only process table that were original and not inserted above");
			sb.AppendLine("					if (fromClause.AnchorAlias == string.Empty)");
			sb.AppendLine("					{");

			var index = 0;
			foreach (var table in _model.Database.Tables.Where(x => x.Generated).OrderBy(x => x.Name))
			{
				if (table.Generated)
				{
					sb.Append("						");
					if (index > 0) sb.Append("else ");
					sb.Append("if (fromClause.TableName == \"" + table.DatabaseName + "\")");
					sb.AppendLine(" whereClause = " + GetLocalNamespace() + ".Business.Objects." + table.PascalName + "Collection.GetRemappedLinqSql(whereClause, fromClause.Alias, fromLinkList);");
					index++;
				}
			}

			sb.AppendLine("					}");
			sb.AppendLine("				}");
			sb.AppendLine("				sb.Append(\"WHERE \" + whereClause);");
			sb.AppendLine("			}");
			sb.AppendLine();
			sb.AppendLine("			sb.AppendLine(\") AS [t0]\");");
			sb.AppendLine("			sb.AppendLine(\"WHERE (Row >= \" + (((paging2.PageIndex - 1) * paging2.RecordsperPage) + 1) + \") AND (Row <= \" + (paging2.PageIndex * paging2.RecordsperPage) + \")\");");
			sb.AppendLine();
			sb.AppendLine("			return sb.ToString();");
			sb.AppendLine("		}");
			sb.AppendLine();

		}

		private void AppendMethodGetSorted()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Creates a sorted dataview of this collection ordered by the specified parameter");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public DataView GetSorted" + _currentView.PascalName + "List(string sortString)");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				return wrappedClass.GetSorted" + _currentView.PascalName + "List(sortString);");
			sb.AppendLine("			}");
			Globals.AppendBusinessEntryCatch(sb);
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendMethodGetEnumerator()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Returns an enumerator that can be used to iterate through the collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <returns>An Enumerator that can iterate through the objects in this collection.</returns>");
			sb.AppendLine("		public System.Collections.IEnumerator GetEnumerator() ");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				return new " + _currentView.PascalName + "Enumerator(wrappedClass.GetEnumerator());");
			sb.AppendLine("			}");
			Globals.AppendBusinessEntryCatch(sb);
			sb.AppendLine("		}");
			sb.AppendLine();

			sb.AppendLine("		System.Collections.Generic.IEnumerator<" + _currentView.PascalName + "> System.Collections.Generic.IEnumerable<" + _currentView.PascalName + ">.GetEnumerator()");
			sb.AppendLine("		{");
			sb.AppendLine("			var retval = new List<" + _currentView.PascalName + ">();");
			sb.AppendLine("			foreach (" + _currentView.PascalName + " item in this)");
			sb.AppendLine("			{");
			sb.AppendLine("				retval.Add(item);");
			sb.AppendLine("			}");
			sb.AppendLine("			return retval.GetEnumerator();");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendRegionSearch()
		{
			sb.AppendLine("		#region Search Members");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Creates a search object to query this collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		IBusinessObjectSearch IBusinessCollection.CreateSearchObject(SearchType searchType)");
			sb.AppendLine("		{");
			sb.AppendLine("			return (IBusinessObjectSearch)this.CreateSearchObject(searchType);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Creates a search object to query this collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public " + _currentView.PascalName + "Search CreateSearchObject(SearchType searchType)");
			sb.AppendLine("		{");
			sb.AppendLine("			return null;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		private void AppendMethodSelectAll()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Execute the cached select commands");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		public static " + _currentView.PascalName + "Collection RunSelect()");
			sb.AppendLine("		{");
			sb.AppendLine("			try");
			sb.AppendLine("			{");
			sb.AppendLine("				var returnVal = new " + _currentView.PascalName + "Collection(Domain" + _currentView.PascalName + "Collection.RunSelect());");
			sb.AppendLine("				return returnVal;");
			sb.AppendLine("			}");
			Globals.AppendBusinessEntryCatch(sb);
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		#endregion

		#region append IList Implementation

		private void AppendMethodContainsIndexOf()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines if the specified item exists in this list");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"item\"></param>");
			sb.AppendLine("		/// <returns></returns>");
			sb.AppendLine("		public virtual bool Contains(" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + " item)");
			sb.AppendLine("		{");
			sb.AppendLine("			foreach (var o in this)");
			sb.AppendLine("			{");
			sb.AppendLine("				if (o == item) return true;");
			sb.AppendLine("			}");
			sb.AppendLine("			return false;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Determines the position in the list of the specified item, if it exists");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"item\"></param>");
			sb.AppendLine("		/// <returns></returns>");
			sb.AppendLine("		public virtual int IndexOf(" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + " item)");
			sb.AppendLine("		{");
			sb.AppendLine("			int index = 0;");
			sb.AppendLine("			foreach (var o in this)");
			sb.AppendLine("			{");
			sb.AppendLine("				if (o == item) return index;");
			sb.AppendLine("				index++;");
			sb.AppendLine("			}");
			sb.AppendLine("			return -1;");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		private void AppendMethodIListInterface()
		{
			sb.AppendLine("		#region IListSource Members");
			sb.AppendLine();
			sb.AppendLine("		bool System.ComponentModel.IListSource.ContainsListCollection");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return true; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		System.Collections.IList System.ComponentModel.IListSource.GetList()");
			sb.AppendLine("		{");
			sb.AppendLine("			var list = new System.Collections.Generic.List<" + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ">();");
			sb.AppendLine("			list.AddRange(this);");
			sb.AppendLine("			return list;");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
			sb.AppendLine("		#region IList Members");
			sb.AppendLine();
			sb.AppendLine("		int System.Collections.IList.Add(object value)");
			sb.AppendLine("		{");
			sb.AppendLine("			throw new System.NotImplementedException();");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		void System.Collections.IList.Clear()");
			sb.AppendLine("		{");
			sb.AppendLine("			throw new System.NotImplementedException();");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		bool System.Collections.IList.Contains(object value)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (!(value is " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + "))");
			sb.AppendLine("				throw new System.Exception(\"The specified type is not valid!\");");
			sb.AppendLine("			var item = value as " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ";");
			sb.AppendLine("			return this.Contains(item);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		int System.Collections.IList.IndexOf(object value)");
			sb.AppendLine("		{");
			sb.AppendLine("			if (!(value is " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + "))");
			sb.AppendLine("				throw new System.Exception(\"The specified type is not valid!\");");
			sb.AppendLine("			var item = value as " + this.GetLocalNamespace() + ".Business.Views." + _currentView.PascalName + ";");
			sb.AppendLine("			return this.IndexOf(item);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		void System.Collections.IList.Insert(int index, object value)");
			sb.AppendLine("		{");
			sb.AppendLine("			throw new System.NotImplementedException();");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		bool System.Collections.IList.IsFixedSize");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return true; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		bool System.Collections.IList.IsReadOnly");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return true; }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		void System.Collections.IList.Remove(object value)");
			sb.AppendLine("		{");
			sb.AppendLine("			//This is a read-only collection");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		void System.Collections.IList.RemoveAt(int index)");
			sb.AppendLine("		{");
			sb.AppendLine("			//This is a read-only collection");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		object System.Collections.IList.this[int index]");
			sb.AppendLine("		{");
			sb.AppendLine("			get { return this[index]; }");
			sb.AppendLine("			set { throw new System.NotImplementedException(); }");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}

		#endregion

		#region append operator overloads
		private void AppendOperatorIndexer()
		{
			sb.AppendLine("		#region Enumerator");
			sb.AppendLine();
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Gets or sets the element at the specified index.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <param name=\"index\">The zero-based index of the element to get or set. </param>");
			sb.AppendLine("		/// <returns>The element at the specified index.</returns>");
			sb.AppendLine("		public " + _currentView.PascalName + " this[int index] ");
			sb.AppendLine("		{");
			sb.AppendLine("			get");
			sb.AppendLine("			{");
			sb.AppendLine("				try");
			sb.AppendLine("				{");
			sb.AppendLine("					var internalEnumerator = this.GetEnumerator();");
			sb.AppendLine("					internalEnumerator.Reset();");
			sb.AppendLine("					int ii = -1;");
			sb.AppendLine("					while(ii < index)");
			sb.AppendLine("					{");
			sb.AppendLine("						internalEnumerator.MoveNext();");
			sb.AppendLine("						ii++;");
			sb.AppendLine("					}");
			sb.AppendLine("					var retval = (" + _currentView.PascalName + ")internalEnumerator.Current;");
			sb.AppendLine("					if (retval.wrappedClass == null)");
			sb.AppendLine("					{");
			sb.AppendLine("						if (!((0 <= index) && (index < this.Count)))");
			sb.AppendLine("							throw new IndexOutOfRangeException();");
			sb.AppendLine("						else");
			sb.AppendLine("							throw new Exception(\"The item is null. This is not a valid state.\");");
			sb.AppendLine("					}");
			sb.AppendLine("					else return (" + _currentView.PascalName + ")internalEnumerator.Current;");
			sb.AppendLine("				}");
			Globals.AppendBusinessEntryCatch(sb, true);
			sb.AppendLine("			}");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.AppendLine("		#endregion");
			sb.AppendLine();
		}
		#endregion

		#region Reject Changes

		private void AppendRejectChanges()
		{
			sb.AppendLine("		/// <summary>");
			sb.AppendLine("		/// Rejects all the changes associate with business object in this collection.");
			sb.AppendLine("		/// </summary>");
			sb.AppendLine("		/// <returns>void</returns>");
			sb.AppendLine("		public void RejectChanges()");
			sb.AppendLine("		{");
			sb.AppendLine("		  var coll = (Domain" + _currentView.PascalName + "Collection)this.wrappedClass;");
			sb.AppendLine("		  coll.RejectChanges();");
			sb.AppendLine("		}");
			sb.AppendLine();
		}

		#endregion

		#region stringbuilders

		protected string GetDefaultForRequiredParam(string codeType)
		{
			if (StringHelper.Match(codeType, "long", true))
			{
				return "long.MinValue";
			}
			else if (StringHelper.Match(codeType, "System.Byte[]", true))
			{
				return "new byte[1]";
			}
			else if (StringHelper.Match(codeType, "bool", true))
			{
				return "false";
			}
			else if (StringHelper.Match(codeType, "string", true))
			{
				return "string.Empty";
			}
			else if (StringHelper.Match(codeType, "System.DateTime", true))
			{
				return "DateTime.MinValue";
			}
			else if (StringHelper.Match(codeType, "System.Decimal", true))
			{
				return "Decimal.MinValue";
			}
			else if (StringHelper.Match(codeType, "System.Double", true))
			{
				return "Double.MinValue";
			}
			else if (StringHelper.Match(codeType, "int", true))
			{
				return "int.MinValue";
			}
			else if (StringHelper.Match(codeType, "System.Single", true))
			{
				return "Single.MinValue";
			}
			else if (StringHelper.Match(codeType, "short", true))
			{
				return "short.MinValue";
			}
			else if (StringHelper.Match(codeType, "object", true))
			{
				return "new object";
			}
			else if (StringHelper.Match(codeType, "System.Byte", true))
			{
				return "System.Byte.MinValue";
			}
			else if (StringHelper.Match(codeType, "System.Guid", true))
			{
				return "System.Guid.Empty";
			}
			else
			{
				throw new Exception("No Default Value For Type Specified");
			}

		}

		#endregion
	}
}